Skip to content

Fix #3067: Flag missing parent type of implicit object as error #3770

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 14, 2018

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Jan 6, 2018

Implicit objects should not allow parent types to be computed from argument
expressions of an application. This is analogous to demanding an explicit type
for implicit vals and defs.

This fix was straightfoward, however it exhibited another problem: Some errors issued
during completion were never reported because the completion happened inside a
TyperState#test that reset the reporter subsequently. The fix for this one was a bit
more involved.

Implicit objects should not allow parent types to be computed from argument
expressions of an application. This is analogous to demanding an explicit type
for implicit vals and defs.
i3067b.scala exhibited a scenario where errors were swallowed because
they were produced during completion in a typer state that was later
reset during a typerState#test. I.e the sequence was

   start test --> complete --> reset typerstate

We avoid that now by marking completer typer state to be shared and
disabling re-using of shared typer states.
@odersky odersky requested a review from smarter January 6, 2018 11:45
@odersky
Copy link
Contributor Author

odersky commented Jan 6, 2018

@nicolasstucki Can you check why i3067 fails the fromTasty test?

@smarter
Copy link
Member

smarter commented Jan 6, 2018

Could we instead restrict the implicit scope used when typing the parents of an implicit object to not contain the object itself?

@nicolasstucki
Copy link
Contributor

I minimized the failure of i3067 from TASTY.

class Test(f: List[String] => List[String])
object o extends Test(_.map(x => x))

The bug is that when we compile from TASTY not all defs of closures are lifted in lambdaLift. In this case x => x is not lifted.

 @scala.annotation.internal.SourceFile("tests/pos/i3067.scala") final module 
    class
   o$ extends Test { 
    def <init>(): Unit = 
      {
        super(o$#o$$superArg$1())
        ()
      }
    private <static> def o$$superArg$1(): Function1 = 
      {
        closure(this.o$$superArg$1$$anonfun$1)
      }
    private <static> def o$$superArg$1$$anonfun$1$$anonfun$1(x: String): String
       = 
    x
    private <static> def o$$superArg$1$$anonfun$1(
      _$1: scala.collection.immutable.List
    ): scala.collection.immutable.List = 
      _$1.map(
        {
          closure(this.o$$superArg$1$$anonfun$1$$anonfun$1)
        }
      , scala.collection.immutable.List.canBuildFrom()).asInstanceOf[
        scala.collection.immutable.List
      ]
  }
  @scala.annotation.internal.SourceFile("tests/pos/i3067.scala") final module 
    class
   o$ extends Test { 
    def <init>(): Unit = 
      {
        super(o$#o$$superArg$1())
        ()
      }
    private <static> def o$$superArg$1(): Function1 = 
      {
        closure(this.o$$superArg$1$$anonfun$1)
      }
    private <static> def o$$superArg$1$$anonfun$1(
      _$1: scala.collection.immutable.List
    ): scala.collection.immutable.List = 
      _$1.map(
        {
          def $anonfun(x: String): String = x
          closure(o.$anonfun)
        }
      , scala.collection.immutable.List.canBuildFrom()).asInstanceOf[
        scala.collection.immutable.List
      ]
  }

@odersky
Copy link
Contributor Author

odersky commented Jan 7, 2018

Could we instead restrict the implicit scope used when typing the parents of an implicit object to not contain the object itself?

And what to do about indirect recursions? Since we decided on demanding full types elsewhere I think it makes sense to not make an exception for objects.

@odersky
Copy link
Contributor Author

odersky commented Jan 7, 2018

@nicolastucki What is a simple command to compile from Tasty that does not involve composing a classpath manually?

@nicolasstucki
Copy link
Contributor

Not really. I will create a way to test from TASTY compilation directly from the sources.

For now, you can replace compileTastyInDir(....) in FromTastyTests with compileTastyInDir("../tests/pos/i3067.scala", defaultOptions) to only test that file only.

@nicolasstucki
Copy link
Contributor

#3786 will add a way to debug from Tasty directly from the sources.

@smarter
Copy link
Member

smarter commented Jan 11, 2018

The markShared scheme seems fragile. It's hard to know for sure all the situations where it could be necessary. I can think of at least FunProto (whose peculiar use of Context is already causing problems: #2412)

@odersky
Copy link
Contributor Author

odersky commented Jan 14, 2018

FunProto is still a sticky point. For now, I know neither of a better solution in general nor have I a concrete amelioration of FunProto. I tried some variations but they all fail tests. We should leave at least one issue open that mentions that or create a new one.

@odersky odersky merged commit fc71ee6 into scala:master Jan 14, 2018
@allanrenucci allanrenucci deleted the fix-#3067 branch January 14, 2018 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants